package com.situ.stmall.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.situ.stmall.entity.Goods;
import com.situ.stmall.entity.Order;
import com.situ.stmall.entity.OrderDetails;
import com.situ.stmall.entity.Shopcart;
import com.situ.stmall.entity.User;
import com.situ.stmall.mapper.GoodsMapper;
import com.situ.stmall.mapper.OrderDetailsMapper;
import com.situ.stmall.mapper.OrderMapper;
import com.situ.stmall.mapper.ShopcartMapper;
import com.situ.stmall.mapper.UserMapper;
import com.situ.stmall.service.OrderService;
import com.situ.stmall.util.MD5Util;

@Service
public class OrderServiceImpl implements OrderService{

	@Autowired
	private OrderMapper orderMapper;
	@Autowired
	private ShopcartMapper cartMapper;
	@Autowired
	private OrderDetailsMapper orderDetailMapper;
	@Autowired
	private GoodsMapper goodsMapper;
	@Autowired
	private UserMapper userMapper;
	
	@Override
	@Transactional // 订单的生成
	public Order add(Integer userId, Integer[] cartIds, Integer addressId) throws Exception{
		
		// 1. 判断cartIds长度
		if (cartIds == null || cartIds.length == 0) {
			throw new Exception("订单中不包含任何商品!!!你还生成个毛线");
		}
		
		List<Shopcart> carts = new ArrayList<>();
		
		// 2. 查询购物车的信息
		for (int i=0; i<cartIds.length; i++) {
			Shopcart cart = cartMapper.selectByPrimaryKey(cartIds[i]);
			carts.add(cart);
			
			// 2.1 验证cart是否存
			if (cart == null) {
				throw new Exception("购物车信息查询失败!!! 订单生成失败");
			}
			// 2.2 验证cart是不是你的
			if (userId != cart.getUserId()) {
				throw new Exception("购物车用户信息出错!!! 订单生成失败");
			}
			// 3.3验证商品库存是否够用
			if (cart.getCount() > cart.getGoods().getCount()) {
				throw new Exception("购买的商品库存不足!!! 订单生成失败");
			}
			// 3.4购物车的购买数量不能为0
			if (cart.getCount() <= 0) {
				throw new Exception("购买的商品数量不能为0!!!订单生成失败");
			}
		}
		
		// 3. 生成订单对象
		Order order = new Order();
		// UUID
		order.setId(UUID.randomUUID().toString());
		order.setUserId(userId);
		order.setAddressId(addressId);
		// 保存到数据库中
		int result = orderMapper.insert(order);
		if (result <= 0 ) {
			// 订单保存失败
			throw new Exception("订单信息保存失败!!!");
		}
		
		// 4. 遍历cart中的数据, 生成订单详情
		for (int i = 0; i < carts.size(); i++) {
			OrderDetails orderDetail = new OrderDetails();
			orderDetail.setOrderId(order.getId());
			orderDetail.setGoodsId(carts.get(i).getGoodsId());
			orderDetail.setCount(carts.get(i).getCount());
			orderDetail.setPrice(carts.get(i).getGoods().getPrice());
			
			// 保存到数据库
			result = orderDetailMapper.insert(orderDetail);
			if (result <= 0) {
				throw new Exception("订单详情保存失败!!!");
			}
			
		}
		
		// 5. 清理购物车的信息
		for (int i = 0; i < carts.size(); i++) {
			result = cartMapper.deleteByPrimaryKey(carts.get(i).getId());
			if (result <= 0) {
				throw new Exception("购物车信息清理失败!!!");
			}

			// 6. 扣除商品的库存
			Goods goods = carts.get(i).getGoods();
			goods.setCount(goods.getCount() - carts.get(i).getCount());
			
			// 写回数据库
			result = goodsMapper.updateByPrimaryKey(goods);
			if (result <= 0) {
				throw new Exception("商品库存扣除失败!!!");
			}
		}
		
		// 7. 查询全部的订单信息返回
		return orderMapper.selectByPrimaryKey(order.getId());
	}

	@Override
	public Order getById(String orderId) {
		return orderMapper.selectByPrimaryKey(orderId);
	}

	@Override
	public int update(Order order) {
		return orderMapper.updateByPrimaryKey(order);
	}

	@Override
	@Transactional
	public int pay(String orderId, String paypwd, Integer userId) throws Exception{
		// 1. 验证支付密码
		User user = userMapper.selectByPrimaryKey(userId);
		System.out.println(MD5Util.getMD5(paypwd));
		if (user.getPaypwd() == null) {
			// 未设置支付密码
			throw new Exception("未设置支付密码");
		}
		if ( ! user.getPaypwd().equals(MD5Util.getMD5(paypwd))) {
			// 密码不对
			throw new Exception("支付密码错误");
		}
		
		// 2. 扣款
		Order order = orderMapper.selectByPrimaryKey(orderId);
		BigDecimal sum = new BigDecimal(0);
		
		for (int i=0; i<order.getOrderDetails().size(); i++) {
			OrderDetails orderDetail = order.getOrderDetails().get(i);
			BigDecimal total = orderDetail.getPrice().multiply(new BigDecimal(orderDetail.getCount()));

			sum = sum.add(total);
		}
		
		if (user.getMoney().compareTo(sum) < 0) {
			// 余额不足
			throw new Exception("账户余额不足!!!");
		}
		
		// 从User上扣除相应的钱
		user.setMoney(user.getMoney().subtract(sum));
		
		// 更新用户的余额
		int result = userMapper.updateByPrimaryKey(user);
		if (result <= 0) {
			// 扣款失败
			throw new Exception("扣款失败, 请求联系管理员!!!");
		}
		
		// 3. 修改订单状态
		if (order.getStatus() != 0) {
			// 订单不是未支付状态, 
			throw new Exception("订单状态错误, 无法完成支付!!!");
		}
		order.setStatus(1); 	// 已支付
		
		result = orderMapper.updateByPrimaryKey(order);
		
		if (result <= 0) {
			// 订单状态修改失败
			throw new Exception("订单修改失败, 无法完成支付!!!");
		}
		
		return 1;
	}

	@Override
	public List getByUserId(Integer userId) {
		return orderMapper.selectByUserId(userId);
	}

	@Override
	@Transactional
	public int clean() {
		// 清理无效订单
		// 什么样的订单才是无效的?, 需要查询出来
		// 时间在半小时之前, 状态是0
		List<Order> orders = orderMapper.selectInvalid();
		
		// 一个个地去清理
		// 删除订单, 删除详情, 库存复原
		for (Order order : orders) {
			for (OrderDetails detail : order.getOrderDetails()) {
				// 库存复原
				Goods goods = detail.getGoods();
				goods.setCount(goods.getCount() + detail.getCount());
				goodsMapper.updateByPrimaryKey(goods);
				
				// 删除详情
				orderDetailMapper.deleteByPrimaryKey(detail.getId());
			}
			
			// 删除当前订单
			orderMapper.deleteByPrimaryKey(order.getId());
		}
				
		return 0;
	}

	@Override
	@Transactional
	public int removeById(String orderId) {
		// 1. 查询订单信息
		Order order = orderMapper.selectByPrimaryKey(orderId);
		
		for (OrderDetails detail : order.getOrderDetails()) {
			// 2. 改库存
			Goods goods = detail.getGoods();
			goods.setCount(goods.getCount() + detail.getCount());
			goodsMapper.updateByPrimaryKey(goods);
			
			// 3. 删除订单详情
			orderDetailMapper.deleteByPrimaryKey(detail.getId());
		}
		
		// 4. 删除订单
		orderMapper.deleteByPrimaryKey(orderId);
		
		return 1;
	}

}
